/*-----------------------------------------------------------------------------
 * @file   dbg_tool.c
 * @brief  debug tools use Serial Port and file log
 * @author WLH<wanglehui8357@163.com> Copyright (C) 2021~2099.
 *---------------------------------------------------------------------------*/
#include "dbg_tool.h"
#include "hal_hrt.h"
#include <stdio.h>

/*-----------------------------------------------------------------------------
 * macro define
-----------------------------------------------------------------------------*/
#define DBG_CACHE_SIZE  128u

/*-----------------------------------------------------------------------------
 * local variable
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
 * local functions
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
 * public functions
-----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
 * Debug Trace functions
-----------------------------------------------------------------------------*/
#if (USE_RTT_TRACE)
#include "SEGGER_RTT.h"
void trace_out(const char* fmt, ...)
{
    int len;
    va_list arg_list;

    char str_buf[DBG_CACHE_SIZE];

    va_start(arg_list, fmt);
    len = vsnprintf(str_buf, DBG_CACHE_SIZE, fmt, arg_list);
    va_end(arg_list);

    assert(len < DBG_CACHE_SIZE);

    if (len < DBG_CACHE_SIZE)
    {
        SEGGER_RTT_WriteString(0, str_buf);
    }
}

void trace_info(const char* fmt, ...)
{
    int len;
    int oft = 0;
    va_list arg_list;

    char str_buf[DBG_CACHE_SIZE];
    str_buf[oft++] = '[';
    str_buf[oft++] = 'I';
    str_buf[oft++] = ']';

    va_start(arg_list, fmt);
    len = vsnprintf(&str_buf[oft], DBG_CACHE_SIZE, fmt, arg_list);
    va_end(arg_list);
    assert(len < (DBG_CACHE_SIZE - oft - 3));

    if (len < (DBG_CACHE_SIZE - oft - 3))
    {
        str_buf[len + oft + 0] = '\r';
        str_buf[len + oft + 1] = '\n';
        str_buf[len + oft + 2] = '\0';

        SEGGER_RTT_WriteString(0, RTT_CTRL_RESET);
        SEGGER_RTT_WriteString(0, str_buf);
    }
}

void trace_warn(const char* fmt, ...)
{
    int len;
    int oft = 0;
    va_list arg_list;

    char str_buf[DBG_CACHE_SIZE];
    str_buf[oft++] = '[';
    str_buf[oft++] = 'W';
    str_buf[oft++] = ']';

    va_start(arg_list, fmt);
    len = vsnprintf(&str_buf[oft], DBG_CACHE_SIZE, fmt, arg_list);
    va_end(arg_list);
    assert(len < (DBG_CACHE_SIZE - oft - 3));

    if (len < (DBG_CACHE_SIZE - oft - 3))
    {
        str_buf[len + oft + 0] = '\r';
        str_buf[len + oft + 1] = '\n';
        str_buf[len + oft + 2] = '\0';

        SEGGER_RTT_WriteString(0, RTT_CTRL_TEXT_BRIGHT_YELLOW);
        SEGGER_RTT_WriteString(0, str_buf);
    }
}

void trace_error(const char* fmt, ...)
{
    int len;
    int oft = 0;
    va_list arg_list;

    char str_buf[DBG_CACHE_SIZE];
    str_buf[oft++] = '[';
    str_buf[oft++] = 'E';
    str_buf[oft++] = ']';

    va_start(arg_list, fmt);
    len = vsnprintf(&str_buf[oft], DBG_CACHE_SIZE, fmt, arg_list);
    va_end(arg_list);
    assert(len < (DBG_CACHE_SIZE - oft - 3));

    if (len < (DBG_CACHE_SIZE - oft - 3))
    {
        str_buf[len + oft + 0] = '\r';
        str_buf[len + oft + 1] = '\n';
        str_buf[len + oft + 2] = '\0';

        SEGGER_RTT_WriteString(0, RTT_CTRL_TEXT_BRIGHT_RED);
        SEGGER_RTT_WriteString(0, str_buf);
    }
}

void trace_buffer(const U8* buf, U32 len)
{
    int i, c;

    while ((int)len > 0)
    {
        SEGGER_RTT_printf(0, "%08X: ", buf);

        for (i = 0; i < 16; i++)
        {
            if (i < (int)len)
            {
                SEGGER_RTT_printf(0, "%02X ", buf[i] & 0xFF);
            }
            else
            {
                SEGGER_RTT_printf(0, "   ");
            }

            if (i == 7)
            {
                SEGGER_RTT_printf(0, " ");
            }
        }

        SEGGER_RTT_printf(0, " |");

        for (i = 0; i < 16; i++)
        {
            if (i < (int)len)
            {
                c = buf[i] & 0xFF;

                if ((c < 0x20) || (c >= 0x7F))
                {
                    c = '.';
                }
            }
            else
            {
                c = ' ';
            }

            SEGGER_RTT_printf(0, "%c", c);
        }

        SEGGER_RTT_printf(0, "|\n");
        len -= 16;
        buf += 16;
    }
}
#else
void trace_out(const char* fmt, ...)
{
    UNUSED(fmt);
}
void trace_info(const char* fmt, ...)
{
    UNUSED(fmt);
}
void trace_warn(const char* fmt, ...)
{
    UNUSED(fmt);
}
void trace_error(const char* fmt, ...)
{
    UNUSED(fmt);
}
void trace_buffer(const U8* buf, U32 len)
{
    UNUSED(buf);
    UNUSED(len);
}
#endif //~USE_RTT_TRACE
